/**
 * 
 */
package com.fnic.pearl.scheduler.mod;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.fnic.pearl.scheduler.SchedulerConfig;
import com.fnic.pearl.scheduler.constant.CondHeaderField;
import com.fnic.pearl.scheduler.constant.SchedulerUrl;
import com.fnic.pearl.scheduler.model.ProbeStatus;
import com.fnic.pearl.scheduler.util.ResponseUtil;

/**
 * 负责探针状态的维护和管理 同时在探针状态变化时上报至 管理节点
 * 
 * @author HuHaiyang
 * @date 2013年10月9日
 */
public class ProbeStatusManager {

	private Logger logger = Logger.getLogger(ProbeStatusManager.class);

	private static ProbeStatusManager instance = new ProbeStatusManager();

	public static ProbeStatusManager getInstance() {
		return instance;
	}

	// 所有探针的当前状态
	private Map<Integer, ProbeStatus> statuses = new HashMap<Integer, ProbeStatus>();

	public synchronized ProbeStatus get(int pid) {
		return statuses.get(pid);
	}

	public synchronized void put(ProbeStatus ps) {
		if (ps != null) {
			statuses.put(ps.getProbeId(), ps);
		}
	}

	/**
	 * 更新探针状态，并上报至 管理节点
	 * 
	 * @param ps
	 *            更新后的探针状态
	 */
	public boolean updateStatus(int probeId, int newStatus) {
		ProbeStatus ps = statuses.get(probeId);
		try {
			if (ps == null) {
				return false;
			}
			if (ps.getStatus() != newStatus) {
				// 同一probe必须在之前请求处理完毕后才能发起新login/logout请求
				ps.get__lock().lock();
				boolean flag = sendStatusToManager(ps, newStatus);
				if (flag == true) {
					// 管理节点校验成功，则设置内存状态
					ps.setStatus(newStatus);
				}
				return flag;
			} else {
				// 旧状态和新状态相同，直接返回
				return true;
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return false;
		} finally {
			if (ps.get__lock().isHeldByCurrentThread()) {
				ps.get__lock().unlock();
			}
		}
	}

	/**
	 * 发送探针状态信息至管理节点 这里只是添加至 AToM 线程队列中
	 * 
	 * @param ps
	 *            探针状态
	 * @return 发送成功返回 true
	 */
	public static boolean sendStatusToManager(ProbeStatus ps, int newStatus) {
		StringBuffer url = new StringBuffer().append("http://").append(SchedulerConfig.getInstance().getManagerIp())
				.append(":").append(SchedulerConfig.getInstance().getManagerPort());
		switch (newStatus) {
		case ProbeStatus.S_LOGOUT:
			url.append(SchedulerUrl.PROBE_LOGOUT);
			break;
		case ProbeStatus.S_LOGIN:
			url.append(SchedulerUrl.PROBE_LOGIN);
			break;
		default:
			return false;
		}
		url.append("?").append(CondHeaderField.COND_PROBE_ID).append("=").append(ps.getProbeId()).append("&")
				.append(CondHeaderField.COND_SCHEDULER_ID).append("=")
				.append(SchedulerConfig.getInstance().getSchedulerId());
		// HttpGet statusRequest = new HttpGet(url.toString());
		// ActiveToManager.getInstance().putRequest(statusRequest);
		return ResponseUtil.sendData(url.toString());
	}

	public synchronized List<ProbeStatus> getAll() {
		List<ProbeStatus> lstProbeStatus = new ArrayList<ProbeStatus>();
		Iterator<ProbeStatus> iter = statuses.values().iterator();
		while (iter.hasNext()) {
			lstProbeStatus.add(iter.next());
		}

		return lstProbeStatus;
	}

	/**
	 * 获取所有登录状态的探针列表
	 * 
	 * @return 返回登录状态的探针列表
	 */
	public synchronized List<ProbeStatus> getAllLogin() {
		List<ProbeStatus> lstProbeStatus = new ArrayList<ProbeStatus>();
		Iterator<ProbeStatus> iter = statuses.values().iterator();
		while (iter.hasNext()) {
			ProbeStatus ps = iter.next();
			if (ps.getStatus() == ProbeStatus.S_LOGIN) {
				lstProbeStatus.add(ps);
			}
		}

		return lstProbeStatus;
	}
}
